#pragma once

#include <base/macro.h>
/* 定义依赖接口const effect, 定义该模块的作用 */

/* CEFF封装, 用于传入参数, 生成不同类型的函数接口 */
/* 用于传递effect接口 */
/* 本质是一样的，为什么不 直接传呢？ */
#define DECL_CEFF(type, name, args)	typedef type (name##_ceff_t) args;

#define __CEFF__(modulename)		const modulename##_chdl_t *hdl

#define CEFF_PARAM(modulename, name)	const modulename##_chdl_t *name


#define __CEFF_HDL(name)		name##_ceff_t * const (name);
#define DECL_CEFF_HDL(typename, ...)	\
typedef struct typename##_chdl_t { MAP(__CEFF_HDL, __VA_ARGS__) } typename##_chdl_t;

#define START_CEFF_HDL(typename, ...)	\
typedef struct typename##_chdl_t {

#define END_CEFF(typename, ...)		} typename##_chdl_t;


/* handler翻译 */
#define NEW_CEFF_HDL(typename, name, ...) \
static const typename##_chdl_t _##name##_in = { __VA_ARGS__ };

#define GET_CEFF_HDL(name)		_##name##_in

/* 输出接口INTF，也需要定义CEFF，也许输入需要的就是输出的 */
#define SINTF_TYPE(name)		__MCAT(name, _sintf_t)
#define DECL_SINTF(type, name, args)	typedef type (SINTF_TYPE(name)) args;

#define __SINTF(name)			SINTF_TYPE(name) * const (name);
#define DECL_MINTF(modulename, ...)	\
typedef struct __MCAT(modulename, _mintf){ MAP(__SINTF, __VA_ARGS__) } __MCAT(modulename, _mintf_t);

#define MINTF(modulename)		const __MCAT(modulename, _mintf_t) *modulename

#define __MINTF_MAP(x)			&x
#define NEW_MINTF(modulename, name, ...) \
static const __MCAT(modulename, _mintf_t) name = { MAPC(__MINTF_MAP, __VA_ARGS__) };


/* 定义输入接口和输出接口连接, 多个输出接口怎么办? */

/* 对于顺序连接的模块，其初始化顺序也应当是顺序的 */
 
/* 模块输入函数和输出函数的获取 */
#define INFUN(comname, name)		const comname##_infun_t * const name
#define INFUN_OF(name)			&__MCAT(name, _infun)
#define OUFUN_OF(name)			&__MCAT(name, _oufun)

#define INFUN_TYPE(comname)		comname##_infun_t
#define OUFUN_TYPE(comname)		comname##_oufun_t

#define NEW_INFUN(comname, name, ...)	static const comname##_infun_t name##_infun = { __VA_ARGS__ };
#define NEW_OUFUN(comname, name, ...)	static const comname##_oufun_t name##_oufun = { __VA_ARGS__ };

/* 方式1 */
#define STA_INFUN(comname)		typedef const struct comname##_infun {
#define END_INFUN(comname)		} comname##_infun_t;
#define STA_OUFUN(comname)		typedef const struct comname##_oufun {
#define END_OUFUN(comname)		} comname##_oufun_t;

/* 将某个模块输出函数声明输入函数 */
#define OU2INFUN(comname0, comname1)	typedef comname0##_oufun_t comname1##_infun_t;
#define OU2OUFUN(comname0, comname1)	typedef comname0##_oufun_t comname1##_oufun_t;

/* 有没有更简洁直观的方式? */
/* infun打包没问题，可以方便内部函数使用 */
/* outfun打包的话就无法传递 */

// #define OUTFUN_comname	(a, b, c ...)
// 直接通过宏获取对应模块的outfun
#define OUFUN(comname)			__MCAT(OUTFUN_, comname)

// #define STA_OUTFUN(typename)	typedef struct typename##_outputf {

// #define END_OUTFUN(typename)	} typename##_outputf_t;	
